<script lang="ts">
export default {
  name: "xt-table",
};
</script>

<script setup lang="ts">
import { computed, ref } from "vue";
import { ElTable } from "element-plus";
import xtTableColumn from "../../../components/xt-table-column/src/main.vue";
import xtTag from "../../xt-tag/src/main.vue";
import { formatTimestamp, matchTagObj } from "../../../utils/utils";
import useRefHook from "../../../hooks/ref";
import type Typings from "../../../typings";

const { INSTANCE, getInstance } = useRefHook();

// 表格类型
interface Props extends /* @vue-ignore */ Typings.Table.tableInstance {
  data?: Typings.Common.plainObj[];
  columns?: Typings.Table.column<Typings.Common.plainObj>[];
  border?: boolean;
  stripe?: boolean;
  showIndex?: boolean;
  rowKey?: string;
  showMultiple?: boolean;
  selectable?: (row: Typings.Common.plainObj) => boolean;
}

const props = withDefaults(defineProps<Props>(), {
  data: () => [],
  columns: () => [],
  border: true,
  stripe: true,
  showIndex: true,
  rowKey: "id",
  showMultiple: false,
});

// 过滤 column
const convertColumn = computed(() => {
  return props.columns.filter((json) => {
    return !(typeof json.isHide === "function" ? json.isHide() : json.isHide);
  });
});

defineExpose({
  getInstance,
});
</script>

<template>
  <el-table
    class="xt-table"
    ref="INSTANCE"
    :data="data"
    :border="border"
    :stripe="stripe"
    :row-key="rowKey"
  >
    <slot>
      <xt-table-column
        v-if="showMultiple"
        key="selection"
        type="selection"
        width="55"
        :reserve-selection="true"
        :selectable="selectable"
      />

      <xt-table-column
        v-if="showIndex"
        key="index"
        type="index"
        label="序号"
        width="60"
        align="center"
      />

      <xt-table-column
        v-for="{
          prop = '',
          label,
          colType = '',
          format,
          options = [],
          renderFn,
          clickFn,
          ...col
        } in convertColumn"
        :key="prop"
        :label="label"
        :prop="prop"
        v-bind="col"
      >
        <template #default="scope">
          <!-- render 函数 -->
          <template v-if="typeof renderFn === 'function'">
            <span v-html="renderFn(scope)"></span>
          </template>

          <!-- 按钮 -->
          <template v-else-if="typeof clickFn === 'function'">
            <a
              class="check-btn primary"
              href="javascript:;"
              @click="clickFn(scope)"
              >{{ scope.row[prop] }}</a
            >
          </template>

          <!-- 时间戳 -->
          <template v-else-if="['time'].includes(colType)">
            {{
              formatTimestamp(scope.row[prop], format || "YYYY-MM-DD HH:mm:ss")
            }}
          </template>

          <!-- tag -->
          <template v-else-if="['tag'].includes(colType)">
            <xt-tag :type="matchTagObj(scope.row[prop], options).type">
              {{ matchTagObj(scope.row[prop], options).name }}
            </xt-tag>
          </template>

          <!-- slot -->
          <template v-else-if="['slot'].includes(colType)">
            <slot :name="prop" v-bind="scope"></slot>
          </template>

          <!-- 其他情况 -->
          <template v-else>
            {{ scope.row[prop] }}
          </template>
        </template>
      </xt-table-column>
    </slot>

    <!-- 操作列插槽 -->
    <slot name="operate"></slot>

    <template #empty>
      <slot name="empty">
        <div class="empty-slot-container">
          <span>暂无数据</span>
        </div>
      </slot>
    </template>
  </el-table>
</template>

<style lang="scss">
@use "../../../scss/xt-table.scss";
</style>
